introduce size_param()
authorKeir Fraser <keir.fraser@citrix.com>
Mon, 31 Aug 2009 09:06:53 +0000 (10:06 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Mon, 31 Aug 2009 09:06:53 +0000 (10:06 +0100)
With there being several instances of custom_param() where the handler
is just invoking parse_size_and_unit(), it seems to make sense to
introduce a simplifying abstraction.

Also fix serial_txbufsz not having been guaranteed to be a power of
two.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
xen/arch/ia64/xen/domain.c
xen/arch/x86/e820.c
xen/common/kernel.c
xen/drivers/char/console.c
xen/drivers/char/serial.c
xen/include/xen/init.h

index c8ba9e28eba4f23272f796b7974e7b077db0bb1b..60b20b53639cc565ad9add23783b57e130b3fb6e 100644 (file)
@@ -2387,11 +2387,7 @@ arch_do_vcpu_op(int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg)
        return rc;
 }
 
-static void __init parse_dom0_mem(char *s)
-{
-       dom0_size = parse_size_and_unit(s, NULL);
-}
-custom_param("dom0_mem", parse_dom0_mem);
+size_param("dom0_mem", dom0_size);
 
 /*
  * Helper function for the optimization stuff handling the identity mapping
index db258ecc82ce247c05f8d7f60ab2b43f66cc5f82..b87990a7f413be0bc63e26d08b50949852ed0afa 100644 (file)
@@ -11,9 +11,8 @@
 #include <asm/msr.h>
 
 /* opt_mem: Limit of physical RAM. Any RAM beyond this point is ignored. */
-unsigned long long opt_mem;
-static void parse_mem(char *s) { opt_mem = parse_size_and_unit(s, NULL); }
-custom_param("mem", parse_mem);
+static unsigned long long __initdata opt_mem;
+size_param("mem", opt_mem);
 
 /* opt_nomtrr_check: Don't clip ram to highest cacheable MTRR. */
 static int __initdata e820_mtrr_clip = -1;
index 971d72310965080b4c0e3e11cd6277021858c439..9dadffec737fedfb4b9f6695fff3008b03d32594 100644 (file)
@@ -92,6 +92,21 @@ void cmdline_parse(char *cmdline)
                     bool_assert = !bool_assert;
                 *(int *)param->var = bool_assert;
                 break;
+            case OPT_SIZE: {
+                uint64_t sz = parse_size_and_unit(optval, NULL);
+                switch ( param->len )
+                {
+                case sizeof(uint32_t):
+                    *(uint32_t *)param->var = sz;
+                    break;
+                case sizeof(uint64_t):
+                    *(uint64_t *)param->var = sz;
+                    break;
+                default:
+                    BUG();
+                }
+                break;
+            }
             case OPT_CUSTOM:
                 ((void (*)(const char *))param->var)(optval);
                 break;
index 3f83745d86aa14f3786e133e04ebbff04fffa65d..98fc4615c450b428e1723154f940b1be97127846 100644 (file)
@@ -59,10 +59,8 @@ static int opt_console_timestamps;
 boolean_param("console_timestamps", opt_console_timestamps);
 
 /* conring_size: allows a large console ring than default (16kB). */
-static uint32_t opt_conring_size;
-static void parse_conring_size(char *s)
-{ opt_conring_size = parse_size_and_unit(s, NULL); }
-custom_param("conring_size", parse_conring_size);
+static uint32_t __initdata opt_conring_size;
+size_param("conring_size", opt_conring_size);
 
 #define _CONRING_SIZE 16384
 #define CONRING_IDX_MASK(i) ((i)&(conring_size-1))
index 3d261caa47a2cf2f973394e0df2dbcebe66dec19..af1fe4f3c7321b4fd69a2ebcfda9472d6fb01920 100644 (file)
 /* #define SERIAL_NEVER_DROP_CHARS 1 */
 
 unsigned int serial_txbufsz = 16384;
-static void __init parse_serial_tx_buffer(const char *s)
-{
-    serial_txbufsz = max((unsigned int)parse_size_and_unit(s, NULL), 512u);
-}
-custom_param("serial_tx_buffer", parse_serial_tx_buffer);
+size_param("serial_tx_buffer", serial_txbufsz);
 
 #define mask_serial_rxbuf_idx(_i) ((_i)&(serial_rxbufsz-1))
 #define mask_serial_txbuf_idx(_i) ((_i)&(serial_txbufsz-1))
@@ -493,9 +489,14 @@ void serial_register_uart(int idx, struct uart_driver *driver, void *uart)
 void serial_async_transmit(struct serial_port *port)
 {
     BUG_ON(!port->driver->tx_empty);
-    if ( port->txbuf == NULL )
-        port->txbuf = alloc_xenheap_pages(
-            get_order_from_bytes(serial_txbufsz), 0);
+    if ( port->txbuf != NULL )
+        return;
+    if ( serial_txbufsz < 512 )
+        serial_txbufsz = 512;
+    while ( serial_txbufsz & (serial_txbufsz - 1) )
+        serial_txbufsz &= serial_txbufsz - 1;
+    port->txbuf = alloc_xenheap_pages(
+        get_order_from_bytes(serial_txbufsz), 0);
 }
 
 /*
index 7e79e52fe35da6c656a8b10326bfba180ecfc1c5..4f9019afe057cf8b43eef97495782d04ca2f3e5a 100644 (file)
@@ -78,7 +78,14 @@ extern initcall_t __initcall_start, __initcall_end;
  */
 struct kernel_param {
     const char *name;
-    enum { OPT_STR, OPT_UINT, OPT_BOOL, OPT_INVBOOL, OPT_CUSTOM } type;
+    enum {
+        OPT_STR,
+        OPT_UINT,
+        OPT_BOOL,
+        OPT_INVBOOL,
+        OPT_SIZE,
+        OPT_CUSTOM
+    } type;
     void *var;
     unsigned int len;
 };
@@ -101,6 +108,10 @@ extern struct kernel_param __setup_start, __setup_end;
     static char __setup_str_##_var[] __initdata = _name; \
     static struct kernel_param __setup_##_var __attribute_used__ \
         __initsetup = { __setup_str_##_var, OPT_UINT, &_var, sizeof(_var) }
+#define size_param(_name, _var) \
+    static char __setup_str_##_var[] __initdata = _name; \
+    static struct kernel_param __setup_##_var __attribute_used__ \
+        __initsetup = { __setup_str_##_var, OPT_SIZE, &_var, sizeof(_var) }
 #define string_param(_name, _var) \
     static char __setup_str_##_var[] __initdata = _name; \
     static struct kernel_param __setup_##_var __attribute_used__ \